# 股票数据API封装模块

import akshare as ak
import pandas as pd
from typing import Dict, List, Union, Optional
import logging
import time
from datetime import datetime, timedelta

logger = logging.getLogger(__name__)

class AKShareAPI:
    """
    AKShare API封装类，提供股票数据获取的基础功能
    """
    @staticmethod
    def get_stock_list() -> pd.DataFrame:
        """
        获取A股股票列表
        
        Returns:
            pd.DataFrame: 包含股票代码、名称等信息的DataFrame
        """
        try:
            stock_info = ak.stock_info_a_code_name()
            return stock_info
        except Exception as e:
            logger.error(f"获取股票列表失败: {str(e)}")
            return pd.DataFrame()
    @staticmethod
    def get_suspended_stocks(symbol: str, date: str = None) -> pd.DataFrame:
        """
        获取停牌股票列表
        
        Returns:
            pd.DataFrame: 包含停牌股票代码、名称等信息的DataFrame
        """
        try:
            suspended_stocks = ak.stock_allotment_cninfo(symbol, "19700101", date)
            return suspended_stocks
        except Exception as e:
            logger.error(f"获取停牌股票列表失败: {str(e)}")
            return pd.DataFrame()
        
    @staticmethod
    def get_stock_daily(symbol: str, start_date: str = None, end_date: str = None) -> pd.DataFrame:
        """
        获取股票日线数据，支持增量获取
        
        Args:
            symbol: 股票代码，如'000001'或'sh000001'
            start_date: 开始日期，格式'YYYYMMDD'，默认为None
            end_date: 结束日期，格式'YYYYMMDD'，默认为当天
        """
        try:
            # 处理股票代码前缀
            if symbol.startswith('8') or symbol.startswith('4') or symbol.startswith('920'):  # 北交所股票
                full_symbol = f"bj{symbol}"
            elif symbol.startswith('6'):
                full_symbol = f"sh{symbol}"
            else:
                full_symbol = f"sz{symbol}"
                
            df = ak.stock_zh_a_daily(symbol=full_symbol, start_date=start_date, end_date=end_date)
                
            if not end_date:
                end_date = datetime.now().strftime('%Y%m%d')
                
            if not start_date:
                start_date = "19900101"
            
            return df
            
        except Exception as e:
            logger.error(f"获取股票{symbol}日线数据失败: {str(e)}")
            return pd.DataFrame()
    @staticmethod
    def get_stock_hqzx(symbol: str) -> pd.DataFrame:
        """
        获取股票当日集中度数据
        
        Args:
            symbol: 股票代码，如'000001'
            
        Returns:
            pd.DataFrame: 包含财报数据的DataFrame
        """
        try:
            # 处理股票代码前缀
            # if symbol.startswith('8') or symbol.startswith('4') or symbol.startswith('920'):  # 北交所股票
            #     full_symbol = f"bj{symbol}"
            # elif symbol.startswith('6'):
            #     full_symbol = f"sh{symbol}"
            # else:
            #     full_symbol = f"sz{symbol}"
            df = ak.stock_cyq_em(symbol=symbol)
            return df
        except Exception as e:
            logger.error(f"获取股票{symbol}财报数据失败: {str(e)}")
            return pd.DataFrame()
    
    @staticmethod
    def get_stock_financial_indicator(symbol: str) -> pd.DataFrame:
        """
        获取股票财务指标数据
        
        Args:
            symbol: 股票代码，如'000001'
            
        Returns:
            pd.DataFrame: 包含PE、PB、ROE等财务指标的DataFrame
        """
        try:
            # 获取财务指标数据
            df = ak.stock_zh_valuation_baidu(symbol=symbol)
            return df
        except Exception as e:
            logger.error(f"获取股票{symbol}财务指标数据失败: {str(e)}")
            return pd.DataFrame()
    
    @staticmethod
    def get_stock_income(symbol: str) -> pd.DataFrame:
        """
        获取股票利润表数据
        
        Args:
            symbol: 股票代码，如'000001'
            
        Returns:
            pd.DataFrame: 包含营收、净利润等数据的DataFrame
        """
        try:
            df = ak.stock_financial_report_sina(symbol=symbol, report_type="利润表")
            return df
        except Exception as e:
            logger.error(f"获取股票{symbol}利润表数据失败: {str(e)}")
            return pd.DataFrame()
    
    @staticmethod
    def get_stock_balance(symbol: str) -> pd.DataFrame:
        """
        获取股票资产负债表数据
        
        Args:
            symbol: 股票代码，如'000001'
            
        Returns:
            pd.DataFrame: 包含资产、负债等数据的DataFrame
        """
        try:
            df = ak.stock_financial_report_sina(symbol=symbol, report_type="资产负债表")
            return df
        except Exception as e:
            logger.error(f"获取股票{symbol}资产负债表数据失败: {str(e)}")
            return pd.DataFrame()
    
    @staticmethod
    def get_stock_cashflow(symbol: str) -> pd.DataFrame:
        """
        获取股票现金流量表数据
        
        Args:
            symbol: 股票代码，如'000001'
            
        Returns:
            pd.DataFrame: 包含现金流量数据的DataFrame
        """
        try:
            df = ak.stock_financial_report_sina(symbol=symbol, report_type="现金流量表")
            return df
        except Exception as e:
            logger.error(f"获取股票{symbol}现金流量表数据失败: {str(e)}")
            return pd.DataFrame()
    
    @staticmethod
    def get_stock_industry() -> pd.DataFrame:
        """
        获取股票行业分类数据
        
        Returns:
            pd.DataFrame: 包含股票代码、行业分类等信息的DataFrame
        """
        try:
            df = ak.stock_sector_spot(indicator="板块名称")
            return df
        except Exception as e:
            logger.error(f"获取股票行业分类数据失败: {str(e)}")
            return pd.DataFrame()
        
    @staticmethod
    def get_trading_holidays() -> pd.DataFrame:
        try:
            df = ak.tool_trade_date_hist_sina()
            return df
        except Exception as e:
            logger.error(f"获取股票分钟数据失败: {str(e)}")
            return pd.DataFrame()
        
    @staticmethod
    def get_detail_data(symbol: str = "sz000001") -> pd.DataFrame:
        try:
             # 处理股票代码前缀
            if symbol.startswith('8') or symbol.startswith('4') or symbol.startswith('920'):  # 北交所股票
                full_symbol = f"bj{symbol}"
            elif symbol.startswith('6'):
                full_symbol = f"sh{symbol}"
            else:
                full_symbol = f"sz{symbol}"
            df = ak.stock_zh_a_tick_tx_js(full_symbol)
            return df
        except Exception as e:
            logger.error(f"获取3秒级分笔数据失败: {str(e)}")
            return pd.DataFrame()
        
    @staticmethod
    def stock_zh_a_spot_em() -> pd.DataFrame:
        """
        获取实时行情数据
        
        Args:
            symbol: 股票代码，如'000001'
            
        Returns:
            pd.DataFrame: 包含实时行情数据的DataFrame
        """
        try:
            df = ak.stock_zh_a_spot_em()
            return df
        except Exception as e:
            logger.error(f"获取实时行情数据失败: {str(e)}")
            return pd.DataFrame()
    
    

    # select=date,close,volume,high,low,prevClose,avg
    # https://yunhq.sse.com.cn:32042/v1/sh1/mink/000002?select=date%2Cclose%2Cvolume%2Chigh%2Clow%2CprevClose%2Cavg&begin=0&end=-1&period=20250114
    # 北交所https://www.bse.cn/companyEchartsController/getKLine/list/832023.do?%7B%22begin%22%3A0%2C%22end%22%3A-1%2C%22type%22%3A%22dayKline%22%2C%22xxfcbj%22%3A2%7D&begin=0&end=-1&type=dayKline&xxfcbj=2&period=20250110
    # 深交所https://www.szse.cn/api/report/ShowReport?SHOWTYPE=xlsx&CATALOGID=1815_stock_snapshot&TABKEY=tab1&txtBeginDate=2025-04-07&txtEndDate=2025-04-07&archiveDate=2023-04-03&random=0.8248172354672991
    # stock_zh_a_spot_em 实时接口